package ngamejava2;

import java.applet.Applet;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Container;
import java.awt.Graphics2D;
import java.awt.Window;
import java.io.IOException;
import javax.xml.xpath.XPathExpressionException;
import org.w3c.dom.Node;

abstract public class BaseGame extends Canvas implements iGameLoopListener, iGameLifeCicleListener
{
	private GameLoop gameLoop;
	private PlaneManager mainPlaneManager;

	public void start()
	{
		setIgnoreRepaint(true);
		addKeyListener(InputManager.getInstance());
		SystemFacade.initInstance(new CanvasSystemFacade(this));
		gameLoop = new GameLoop();
		gameLoop.setListener(this);
		gameLoop.start();
	}

	public void stop()
	{
		removeKeyListener(InputManager.getInstance());
		gameLoop.terminate();
		gameLoop = null;
	}

	public void terminate()
	{
		if (gameLoop != null)
		{
			gameLoop.terminate();
		}
		Container o = getParent();
		int c = 0;
		while (o != null && !(o instanceof Window) && !(o instanceof Applet) && c < 10)
		{
			o = o.getParent();
		}
		if (o instanceof Window)
		{
			((Window) o).dispose();
		}
	}

	public void setFullScreen(boolean value)
	{
		SystemFacade.getInstance().setFullScreen(value);
	}

	public boolean isFullScreen()
	{
		return SystemFacade.getInstance().isFullScreen();
	}

	public void gameLoopUpdate(long currentTick)
	{
		SystemFacade.getInstance().update(currentTick);
		if (mainPlaneManager != null)
		{
			mainPlaneManager.update(currentTick);
		}
		update(currentTick);
	}

	public void gameLoopRender(long currentFrame)
	{
		Graphics2D g = SystemFacade.getInstance().getGraphics();
		g.setColor(Color.black);
		g.fillRect(0, 0, SystemFacade.getInstance().getWidth(), SystemFacade.getInstance().getHeight());

		if (mainPlaneManager != null)
		{
			g.setClip(mainPlaneManager.getViewport());
			g.setColor(Color.blue);
			g.fill(mainPlaneManager.getViewport());
			mainPlaneManager.render(g, currentFrame);
		}

		render((Graphics2D) g.create(), currentFrame);
		g.setColor(Color.black);
		g.fillRect(getWidth() / 2 - 100, 0, 250, 20);
		g.setColor(Color.white);
		if (gameLoop != null)
		{
			g.drawString("TPS: " + gameLoop.getSpeedTracker().getTPS() + "/" + gameLoop.getExpectedTPS() + "          FPS: " + gameLoop.getSpeedTracker().getFPS() + "          IDLE: " + gameLoop.
					getSpeedTracker().getIdleLoopsPerSecond(), getWidth() / 2 - 100 + 10, 15);
		}
		g.dispose();
		SystemFacade.getInstance().render(currentFrame);
	}

	public void gameLoopLoad()
	{
		SystemFacade.getInstance().load();
		load();
		if (mainPlaneManager != null)
		{
			mainPlaneManager.load();
		}
	}

	public void gameLoopUnload()
	{
		if (mainPlaneManager != null)
		{
			mainPlaneManager.unload();
		}
		unload();
		SystemFacade.getInstance().unload();
	}

	public void setMainPlaneManager(PlaneManager aPlaneManager)
	{
		mainPlaneManager = aPlaneManager;
	}

	public PlaneManager getMainPlaneManager()
	{
		return mainPlaneManager;
	}

	public void load()
	{
	}

	public void unload()
	{
	}

	public void update(long currentTick)
	{
	}

	public void render(Graphics2D g, long currentFrame)
	{
	}

	public void write(GameWriter gw) throws IOException
	{
		gw.write("mainPlaneManager", mainPlaneManager);
	}

	public void read(GameReader gr, Node gameNode) throws XPathExpressionException, InstantiationException, IllegalAccessException, ClassNotFoundException
	{
		setMainPlaneManager((PlaneManager) gr.readObject(gameNode, "object[@name='mainPlaneManager']"));
	}
}